package com.feilo.main;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.hslf.extractor.PowerPointExtractor;
import org.apache.poi.hssf.extractor.ExcelExtractor;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xssf.extractor.XSSFExcelExtractor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

public class ParseText {

	// 读取Word97-2003的全部内容 doc
	private static String getTextFromWord(byte[] file) {
		String text = "";
		ByteArrayInputStream fis = null;
		WordExtractor ex = null;
		try {
			// word 2003 ,图片不会被读取
			fis = new ByteArrayInputStream(file);
			ex = new WordExtractor(fis);
			text = ex.getText();
			ex.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return text;
	}

	// 读取Word2007+的全部内容 docx
	private static String getTextFromWord2007(byte[] file) {
		String text = "";
		ByteArrayInputStream fis = null;
		XWPFDocument doc = null;
		XWPFWordExtractor ex = null;
		try {
			fis = new ByteArrayInputStream(file);
			doc = new XWPFDocument(fis);
			ex = new XWPFWordExtractor(doc);
			text = ex.getText();
			ex.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return text;
	}

	// 读取Excel97-2003的全部内容 xls
	private static String getTextFromExcel(byte[] file) {
		String text = "";
		ByteArrayInputStream fis = null;
		HSSFWorkbook wb = null;
		ExcelExtractor ex = null;
		try {
			fis = new ByteArrayInputStream(file);
			wb = new HSSFWorkbook(new POIFSFileSystem(fis));
			ex = new ExcelExtractor(wb);
			ex.setFormulasNotResults(false);
			ex.setIncludeSheetNames(false);
			text = ex.getText();
			ex.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return text;
	}

	// 读取Excel2007+的全部内容 xlsx
	private static String getTextFromExcel2007(byte[] file) {
		String text = "";
		ByteArrayInputStream fis = null;
		XSSFWorkbook wb = null;
		XSSFExcelExtractor ex = null ;
		try {
			fis = new ByteArrayInputStream(file);
			wb = new XSSFWorkbook(fis);
			ex = new XSSFExcelExtractor(wb);
			ex.setIncludeSheetNames(false);
			text = ex.getText();
			ex.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return text;
	}

	// 读取Powerpoint97-2003的全部内容 ppt
	private static String getTextFromPPT(byte[] file) {
		String text = "";
		ByteArrayInputStream fis = null;
		PowerPointExtractor ex = null;
		try {
			// PowerPoint 2003 ,图片不会被读取
			fis = new ByteArrayInputStream(file);
			ex = new PowerPointExtractor(fis);
			text = ex.getText();
			ex.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return text;
	}

	// 抽取幻灯片2007+全部内容 pptx
	private static String getTextFromPPT2007(byte[] file) {
		String text = "";
		ByteArrayInputStream fis = null;
		XMLSlideShow slide = null;
		try {
			// PowerPoint 2003 ,图片不会被读取
			fis = new ByteArrayInputStream(file);
			slide = new XMLSlideShow(fis);
			XSLFPowerPointExtractor ex = new XSLFPowerPointExtractor(slide);
			text = ex.getText();
			ex.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return text;
	}

	// 读取pdf文件
	private static String getTextFromPDF(byte[] file) {
		String text = "";
		PDDocument pdfdoc = null;
		ByteArrayInputStream is = null;
		try {
			is = new ByteArrayInputStream(file);
			pdfdoc = PDDocument.load(is);
			PDFTextStripper stripper = new PDFTextStripper();
			text = stripper.getText(pdfdoc);

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (pdfdoc != null) {
					pdfdoc.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return text;
	}

	// 读取txt文件
	private static String getTextFromTxt(byte[] file) {
		String text = "";
		try {
			String encoding = getCharset(file);
			text = new String(file, encoding);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		return text;
	}

	// 获得txt文件编码方式
	private static String getCharset(byte[] file) throws IOException {
		String charset = "GBK";
		byte[] first3Bytes = new byte[3];
		ByteArrayInputStream bis = null;
		try {
			boolean checked = false;
			bis = new ByteArrayInputStream(file);
			bis.mark(0);
			int read = bis.read(first3Bytes, 0, 3);
			if (read == -1) {
				return charset;
			}
			if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) {
				charset = "UTF-16LE";
				checked = true;
			} else if (first3Bytes[0] == (byte) 0xFE && first3Bytes[1] == (byte) 0xFF) {
				charset = "UTF-16BE";
				checked = true;
			} else if (first3Bytes[0] == (byte) 0xEF && first3Bytes[1] == (byte) 0xBB
					&& first3Bytes[2] == (byte) 0xBF) {
				charset = "UTF-8";
				checked = true;
			}
			bis.reset();
			if (!checked) {
				while ((read = bis.read()) != -1) {
					if (read >= 0xF0) {
						break;
					}
					if (0x80 <= read && read <= 0xBF) {// 单独出现BF以下的，也算是GBK
						break;
					}
					if (0xC0 <= read && read <= 0xDF) {
						read = bis.read();
						if (0x80 <= read && read <= 0xBF) // 双字节 (0xC0 - 0xDF)
							// (0x80 - 0xBF),也可能在GB编码内
							continue;
						else
							break;
					} else if (0xE0 <= read && read <= 0xEF) {// 也有可能出错，但是几率较小
						read = bis.read();
						if (0x80 <= read && read <= 0xBF) {
							read = bis.read();
							if (0x80 <= read && read <= 0xBF) {
								charset = "UTF-8";
								break;
							} else {
								break;
							}
						} else {
							break;
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bis != null) {
				bis.close();
			}
		}
		return charset;
	}
	
	// 判断文档类型，调用不同的解析方法
	public static String parse(String path, String suffix) {
		return parse(getBytes(path),suffix);
	}

	// 判断文档类型，调用不同的解析方法
	public static String parse(byte[] buffer, String suffix) {
		String text = "";
		switch (suffix) {
		case "doc":
			text = getTextFromWord(buffer);
			break;
		case "docx":
			text = getTextFromWord2007(buffer);
			break;
		case "xls":
			text = getTextFromExcel(buffer);
			break;
		case "xlsx":
			text = getTextFromExcel2007(buffer);
			break;
		case "ppt":
			text = getTextFromPPT(buffer);
			break;
		case "pptx":
			text = getTextFromPPT2007(buffer);
			break;
		case "pdf":
			text = getTextFromPDF(buffer);
			break;
		case "txt":
			text = getTextFromTxt(buffer);
			break;
		default:
			System.out.println("不支持解析文档类型");
		}
		return text.replace("\\s*", "");
	}
	
	/** 
     * 获得指定文件的byte数组 
     */
	private static byte[] getBytes(String filePath){  
        byte[] buffer = null;  
        try {  
            File file = new File(filePath);  
            FileInputStream fis = new FileInputStream(file);  
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);  
            byte[] b = new byte[1000];  
            int n;  
            while ((n = fis.read(b)) != -1) {  
                bos.write(b, 0, n);  
            }  
            fis.close();  
            bos.close();  
            buffer = bos.toByteArray();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        return buffer;  
    }
	
	/** 
     * 根据byte数组，生成文件 
     */  
    public static void toFile(byte[] bfile, String filePath,String fileName) {  
        BufferedOutputStream bos = null;  
        FileOutputStream fos = null;  
        File file = null;  
        try {  
            File dir = new File(filePath);  
            if(!dir.exists()&&dir.isDirectory()){//判断文件目录是否存在  
                dir.mkdirs();  
            }  
            file = new File(filePath+"\\"+fileName);  
            fos = new FileOutputStream(file);  
            bos = new BufferedOutputStream(fos);  
            bos.write(bfile);  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            if (bos != null) {  
                try {  
                    bos.close();  
                } catch (IOException e1) {  
                    e1.printStackTrace();  
                }  
            }  
            if (fos != null) {  
                try {  
                    fos.close();  
                } catch (IOException e1) {  
                    e1.printStackTrace();  
                }  
            }  
        }  
    }  

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String text = ParseText.parse(ParseText.getBytes("D:\\UML基础教程-非常好.pdf"), "pdf");
		System.out.println(text);
		ParseText.toFile(text.getBytes(), "D:\\", "UML基础教程-非常好.txt");
	}

}
